"""
@author: 江同学呀
@file: nested_field.py
@date: 2024/7/27 17:58
@desc:
    https://www.elastic.co/guide/en/elasticsearch/reference/7.17/nested.html

    A JSON object that preserves the relationship between its subfields.
    一个 JSON 对象，用于保留其子字段之间的关系。
"""
from abc import ABC
from typing import List, Dict, Union, Type, Iterable

from espc.common.field_common import Dynamic
from espc.orm.model.base.base import _Base
from espc.orm.model.mapping.field.base_field.base_field import _BaseField
from espc.orm.model.mapping.field.field_attribute import DynamicAttribute, PropertiesAttribute, IncludeInParentAttribute, \
    IncludeInRootAttribute
from espc.orm.model.properties import Properties
from espc.utils.build_add_attr import build_add_attr


class NestedField(
    _BaseField, DynamicAttribute, PropertiesAttribute, IncludeInParentAttribute, IncludeInRootAttribute, ABC
):
    """
    嵌套 字段
    """
    _field_type: str = "nested"
    # todo 递归路径
    _path: str

    def __init__(
            self, field_name: str = None, value: List[Dict] = None, default: List[Dict] = None,
            dynamic: Union[str, bool, Dynamic] = None, properties: Iterable[_BaseField] = None,
            include_in_parent: bool = None, include_in_root: bool = None,
    ):
        super().__init__(
            field_name=field_name, value=value, default=default, dynamic=dynamic, properties=properties,
            include_in_parent=include_in_parent, include_in_root=include_in_root,
        )
        return

    def __get__(self, instance: _Base, owner: Type["NestedField"]) -> Union["NestedField", List[Dict]]:
        return super(NestedField, self).__get__(instance=instance, owner=owner)

    def __set__(self, instance, value: List[Dict]):
        super(NestedField, self).__set__(instance=instance, value=value)
        return

    @property
    def value(self) -> List[Dict]:
        return self._value

    @value.setter
    def value(self, value: List[Dict]):
        self._value: List[Dict] = value
        return

    @build_add_attr
    def _build(self) -> Dict:
        mapping: Dict = {
            "type": self._field_type
        }
        return mapping


